<!DOCTYPE html>
<html>

<head>
    <style>
        html,
        body {
            padding: 0;
            margin: 0;
            height: 100%;
        }

        /* 垂直分割线 */
        .vertical_line {
            position: absolute;
            top: 12%;
            left: 45%;
            bottom: 4.2%;
            z-index: 1;
            float: left;
            width: 10px;
            background-color: rgba(50, 50, 50, 0.75);
            user-select: none;
        }

        /* 设置存放地图div的样式 */
        #esri_left_dom_id {
            position: absolute;
            top: 12%;
            bottom: 4.5%;
            left: 2.4%;
            right: 2.4%;
        }

        /* 圆按钮 */
        .circle {
            width: 30px;
            height: 30px;
            background-color: rgba(50, 50, 50, 0.75);
            border-radius: 50%;
            position: absolute;
            top: 40%;
            left: 40%;
            bottom: 4.2%;
            z-index: 2;
            margin-left: -10px;
            user-select: none;
        }

        #esri_right_dom_id {
            position: absolute;
            top: 12%;
            bottom: 4.5%;
            left: 2.4%;
            right: 2.4%;
            z-index: -1;
        }

        /* 左箭头 */
        .triangle-left {
            width: 0;
            height: 0;
            border-top: 4px solid transparent;
            border-right: 7px solid white;
            border-bottom: 4px solid transparent;
            position: absolute;
            top: 40%;
            margin-left: -8px;
            margin-top: 12px;
            z-index: 3;
            user-select: none;
        }

        /* 右箭头 */
        .triangle-right {
            width: 0;
            height: 0;
            border-top: 4px solid transparent;
            border-left: 7px solid white;
            border-bottom: 4px solid transparent;
            position: absolute;
            top: 40%;
            margin-left: 10px;
            margin-top: 12px;
            z-index: 3;
            user-select: none;
        }
    </style>

    <link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.12/"></script>
    <script>
        require([
            "esri/Map",
            "esri/views/SceneView",
            "esri/core/watchUtils",
            'dojo/dom-style',
        ], function (Map, SceneView, watchUtils, EsriDomStyle) {
            var esriContainerDiv = 'esri_left_dom_id'
            var esriSwipeContainerDiv = 'esri_right_dom_id'
            var map = new Map({
                basemap: "satellite"
            });
            var map2 = new Map({
                basemap: "osm"
            });

            var view1 = new SceneView({
                container: esriContainerDiv,
                map: map
            });

            var view2 = new SceneView({
                container: esriSwipeContainerDiv,
                map: map2,
            });
            view1.ui.remove(['attribution', 'zoom', 'navigation-toggle', 'compass'])
            view2.ui.remove(['attribution', 'zoom', 'navigation-toggle', 'compass'])
            var isSlitLineDragging = false // 分割线移动状态
            document.getElementById('swipe_split_box').onmousedown = function () {
                isSlitLineDragging = true
            }
            document.getElementById('swipe_split_box').onmouseup = function () {
                isSlitLineDragging = false
            }
            /**
             * 分割线移动事件
             * @param {Object} e 分割线移动事件对象
             */
            function pointMove(e) {
                e.stopPropagation()
                updateMapSwipeLocation(e.x)
            };
            /**
             * 更新卷帘地图容器展开位置
             * @param {Number} location 当前的位置
             * @param {Boolean} isInit 是否是初始化
             */
            function updateMapSwipeLocation(location, isInit) {
                const swipeMap = document.getElementById(esriSwipeContainerDiv).getBoundingClientRect()
                const offsetX = location
                if (isSlitLineDragging || isInit) {
                    EsriDomStyle.set(esriSwipeContainerDiv, 'z-index', '1')
                    EsriDomStyle.set(esriSwipeContainerDiv, 'clip', 'rect(0px,' + offsetX + 'px, ' + swipeMap
                        .height + 'px,0px)')
                    EsriDomStyle.set('vertical_line', 'left', (offsetX - 5 + (swipeMap.width * 0.024)) + 'px ')
                    EsriDomStyle.set('swipe_circle', 'left', (offsetX - 5 + (swipeMap.width * 0.024)) + 'px ')
                    EsriDomStyle.set('swipe_triangle_left', 'left', (offsetX - 5 + (swipeMap.width * 0.024)) +
                        'px ')
                    EsriDomStyle.set('swipe_triangle_right', 'left', (offsetX - 5 + (swipeMap.width * 0.024)) +
                        'px ')
                }
            };
            /**
             * 同步两个视图容器
             * @param {Object} view 视图容器
             * @param {Object} others 其它的视图容器
             * @return {Object} 监听事件
             */
            function synchronizeView(view, others) {
                others = Array.isArray(others) ? others : [others]

                let viewpointWatchHandle
                let viewStationaryHandle
                let otherInteractHandlers
                let scheduleId

                const clear = function () {
                    if (otherInteractHandlers) {
                        otherInteractHandlers.forEach(function (handle) {
                            handle.remove()
                        })
                    }
                    viewpointWatchHandle && viewpointWatchHandle.remove()
                    viewStationaryHandle && viewStationaryHandle.remove()
                    scheduleId && clearTimeout(scheduleId)
                    otherInteractHandlers = viewpointWatchHandle = viewStationaryHandle = scheduleId = null
                }

                const interactWatcher = view.watch('interacting, animation', (newValue) => {
                    if (!newValue) {
                        return
                    }
                    if (viewpointWatchHandle || scheduleId) {
                        return
                    }

                    // start updating the other views at the next frame
                    scheduleId = setTimeout(function () {
                        scheduleId = null
                        viewpointWatchHandle = view.watch('viewpoint', (newValue) => {
                            others.forEach(function (otherView) {
                                otherView.viewpoint = newValue
                            })
                        })
                    }, 0)
                    const that = this
                    // stop as soon as another view starts interacting, like if the user starts panning
                    otherInteractHandlers = others.map(function (otherView) {
                        return watchUtils.watch(otherView, 'interacting,animation',
                            (value) => {
                                if (value) {
                                    clear()
                                }
                            }
                        )
                    })

                    // or stop when the view is stationary again
                    viewStationaryHandle = watchUtils.whenTrue(view, 'stationary', clear)
                })

                return {
                    remove: function () {
                        this.remove = function () {}
                        clear()
                        interactWatcher.remove()
                    },
                }
            };
            /**
             * 同步两个视图容器入口函数
             * @param {Object} views 多个视图容器
             * @return {Object} 移除事件
             */
            function synchronizeViews(views) {
                let handles = views.map(function (view, idx, views) {
                    const others = views.concat()
                    others.splice(idx, 1)
                    return synchronizeView(view, others)
                })
                return {
                    remove: function () {
                        this.remove = function () {}
                        handles.forEach(function (h) {
                            h.remove()
                        })
                        handles = null
                    },
                }
            };
            view1.on('pointer-move', (e) => {
                pointMove(e)
            })
            view2.on('pointer-move', (e) => {
                pointMove(e)
            })
            // 设置初始位置
            const swipeMap = document.getElementById(esriSwipeContainerDiv).getBoundingClientRect()
            updateMapSwipeLocation(swipeMap.width * 0.5, true)
            // 同步视图
            synchronizeViews([view1, view2])
        })
    </script>
</head>

<body>
    <div id='esri_left_dom_id'></div>
    <div id='esri_right_dom_id'></div>
    <div id="swipe_split_box">
        <div id="vertical_line" class="vertical_line"></div>
        <div id="swipe_circle" class="circle"></div>
        <div id="swipe_triangle_left" class="triangle-left"></div>
        <div id="swipe_triangle_right" class="triangle-right"></div>
    </div>
</body>

</html>